/*
 * RPi_UART.c
 *
 *  Created on: 2013/03/12
 *      Author: muneo
 */
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <sys/signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#include "RPi_UART.h"

// グローバル変数宣言。
struct termios g_UART_old_term_io;		// 現在の設定の退避用。

int UART_open(char *serial_dev)
{
	struct termios new_term_io;
	int uart_fd;

	// デバイスをオープン。
	uart_fd = open(serial_dev, O_RDWR | O_NOCTTY);
	if (uart_fd < 0)
	{
		/// デバイスオープンに失敗。
		perror(serial_dev);
		return(-1);
	}

	// 既存の設定を取得・保存。
	tcgetattr(uart_fd, &g_UART_old_term_io);

	// new_term_ioの制御文字の初期化。
	new_term_io.c_iflag = 0;
	new_term_io.c_oflag = 0;
	new_term_io.c_cflag = 0;
	new_term_io.c_lflag = 0;
	new_term_io.c_line = 0;
	//bzero(new_term_io.c_cc, sizeof(new_term_io.c_cc));
	memset(new_term_io.c_cc, '\0', sizeof(new_term_io.c_cc));

	// ポートの設定。
	//  B9600 = 9600bps
	//  CS8 = 8bit, no parity, 1 stopbit
	//  CLOCAL = ローカル接続（モデム制御なし）
	//  CREAD = 受信文字有効。
	new_term_io.c_cflag = B9600 | CS8 | CLOCAL | CREAD;

	// パリティデータエラーは無視に設定。
	new_term_io.c_iflag = IGNPAR;

	// Rawモード出力。
	new_term_io.c_oflag = 0;
	// 入力モード設定。non-canonical, no echo,
	new_term_io.c_lflag = 0;
	// inter-character timer
	new_term_io.c_cc[VTIME] = 0;
	// 1文字来るまで読み込みをブロック。
	new_term_io.c_cc[VMIN] = 1;

	// モデムラインのクリア。
	tcflush(uart_fd, TCIFLUSH);

	// 新しい設定を適用。
	tcsetattr(uart_fd, TCSANOW, &new_term_io);

	return(uart_fd);
}

void UART_close(int uart_fd)
{
	tcsetattr(uart_fd, TCSANOW, &g_UART_old_term_io);
	close(uart_fd);
}
int UART_putc(unsigned char c, int uart_fd)
{
	if (write(uart_fd, &c, 1) != 1)
		return(-1);

	return(1);
}

int UART_puts(char *s, int uart_fd)
{
	if (write(uart_fd, s, strlen(s)) != strlen(s))
		return(-1);

	return(1);
}
int UART_getc(int uart_fd)
{
	unsigned char c;

	if (read(uart_fd, (char *)&c, 1) != 1)
		return(-1);

	return(c);
}
